Completed
Pull Request — master (#89)
by thomas
53s
created

?!?.map   B

Complexity

Conditions 1
Paths 16

Size

Total Lines 186

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 1 Features 3
Metric Value
cc 1
c 9
b 1
f 3
nc 16
dl 0
loc 186
rs 8.2857
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/* jshint -W101, -W098 */
2
/* global window */
3
var _ = require('lodash');
4
var blocktrail = require('../');
5
var Wallet = blocktrail.Wallet;
6
var assert = require('assert');
7
var crypto = require('crypto');
8
var async = require('async');
9
var bitcoin = require('bitcoinjs-lib');
10
var bip39 = require("bip39");
11
12
var WAIT_FOR_TX_PROCESSED = process.env.BLOCKTRAIL_WAIT_FOR_TX || 300;
13
14
/**
15
 * @type APIClient
16
 */
17
var client = blocktrail.BlocktrailSDK({
18
    apiKey : process.env.BLOCKTRAIL_SDK_APIKEY || window.BLOCKTRAIL_SDK_APIKEY || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APIKEY",
19
    apiSecret : process.env.BLOCKTRAIL_SDK_APISECRET || window.BLOCKTRAIL_SDK_APISECRET || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APISECRET",
20
    testnet : true
21
});
22
23
var TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC = "give pause forget seed dance crawl situate hole keen",
24
    TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC = "give pause forget seed dance crawl situate hole give",
25
    TRANSACTION_TEST_WALLET_PASSWORD = "password";
26
27 View Code Duplication
var _createTestWallet = function(identifier, passphrase, primaryMnemonic, backupMnemonic, segwit, cb) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
28
    var keyIndex = 9999;
29
    var network = client.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
30
31
    var primarySeed = bip39.mnemonicToSeed(primaryMnemonic, passphrase);
32
    var primaryPrivateKey = bitcoin.HDNode.fromSeedBuffer(primarySeed, network);
33
34
    var backupSeed = bip39.mnemonicToSeed(backupMnemonic, "");
35
    var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(backupSeed, network);
36
    var backupPublicKey = backupPrivateKey.neutered();
37
38
    var checksum = primaryPrivateKey.getAddress();
39
    var primaryPublicKey = primaryPrivateKey.deriveHardened(keyIndex).neutered();
40
41
    client.storeNewWalletV1(
42
        identifier,
43
        [primaryPublicKey.toBase58(), "M/" + keyIndex + "'"],
44
        [backupPublicKey.toBase58(), "M"],
45
        primaryMnemonic,
46
        checksum,
47
        keyIndex,
48
        segwit
49
    ).then(function(result) {
50
        var blocktrailPublicKeys = _.mapValues(result.blocktrail_public_keys, function(blocktrailPublicKey) {
51
            return bitcoin.HDNode.fromBase58(blocktrailPublicKey[0], network);
52
        });
53
54
        var wallet = new blocktrail.Wallet(
55
            client,
56
            identifier,
57
            blocktrail.Wallet.WALLET_VERSION_V1,
58
            primaryMnemonic,
59
            null,
60
            null,
61
            {keyIndex: primaryPublicKey},
62
            backupPublicKey,
63
            blocktrailPublicKeys,
64
            keyIndex,
65
            result.segwit || 0,
66
            client.testnet,
67
            checksum
68
        );
69
70
        wallet.unlock({
71
            passphrase: passphrase
72
        }, function(err) {
73
            cb(err, wallet);
74
        });
75
76
    }, function(err) {
77
        return cb(err);
78
    });
79
};
80
81
var createDiscoveryTestWallet = function(identifier, passphrase, cb) {
82
    var primaryMnemonic = "give pause forget seed dance crawl situate hole kingdom";
83
    var backupMnemonic = "give pause forget seed dance crawl situate hole course";
84
85
    return _createTestWallet(identifier, passphrase, primaryMnemonic, backupMnemonic, false, cb);
86
};
87
88
var createTransactionTestWallet = function(identifier, segwit, cb) {
89
    return _createTestWallet(
90
        identifier,
91
        TRANSACTION_TEST_WALLET_PASSWORD,
92
        TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC,
93
        TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC,
94
        segwit,
95
        cb
96
    );
97
};
98
99
var createRecoveryTestWallet = function(identifier, passphrase, cb) {
100
    var primaryMnemonic = "give pause forget seed dance crawl situate hole join";
101
    var backupMnemonic = "give pause forget seed dance crawl situate hole crater";
102
103
    return _createTestWallet(identifier, passphrase, primaryMnemonic, backupMnemonic, false, cb);
104
};
105
106
describe('Initialize with check_backup_key', function() {
107
    it('rejects invalid inputs', function(cb) {
108
        try {
109
            client.initWallet({
110
                identifier: "unittest-transaction",
111
                password: "password",
112
                check_backup_key: []
113
            });
114
            assert(false);
115
        } catch (e) {
116
            assert.equal("Invalid input, must provide the backup key as a string (the xpub)", e.message);
117
        }
118
        cb();
119
    });
120
121
    it('checks against the string', function(cb) {
122
        client.initWallet({
123
            identifier: "unittest-transaction",
124
            password: "password",
125
            check_backup_key: 'for demonstration purposes only'
126
        }, function(err, _wallet) {
0 ignored issues
show
Unused Code introduced by
The parameter _wallet is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
127
            assert.ok(err);
128
            assert.equal("Backup key returned from server didn't match our own copy", err.message);
129
            cb();
130
        });
131
    });
132
133
    it('allows if the backup key matches', function(cb) {
134
        // You wouldn't keep your backup seed in your code,
135
        // dump it from the wallet upon generation
136
137
        var backupSeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC, "");
138
        var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(backupSeed, bitcoin.networks.testnet);
139
        var backupPublicKey = backupPrivateKey.neutered();
140
        var xpub = backupPublicKey.toBase58();
141
142
        // Would be saves as a string in code..
143
        client.initWallet({
144
            identifier: "unittest-transaction",
145
            password: "password",
146
            check_backup_key: xpub
147
        }, function(err, _wallet) {
148
            assert.ifError(err);
149
            assert.ok(_wallet);
150
            cb();
151
        });
152
    });
153
});
154
155
/**
156
 * Test operations on v2 and v3 wallets.
157
 * Also tests the default, encouraging to look at this test if it changes again.
158
 */
159
[
160
  blocktrail.Wallet.WALLET_VERSION_V2,
161
  blocktrail.Wallet.WALLET_VERSION_V3,
162
  null /* test our assumed default version */
163
].map(function(walletVersion) {
164
    var assumedDefault = blocktrail.Wallet.WALLET_VERSION_V3;
165
    describe('test new blank wallet, ' + walletVersion, function() {
166
        var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
167
        var wallet;
168
169
        after(function(cb) {
170
            if (wallet) {
171
                wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
172
                    cb();
173
                });
174
            } else {
175
                cb();
176
            }
177
        });
178
179
        it("shouldn't already exist", function(cb) {
180
            client.initWallet({
181
                identifier: myIdentifier,
182
                readOnly: true
183
            }, function(err, wallet) {
184
                assert.ok(err);
185
                assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
186
187
                cb();
188
            });
189
        });
190
191
        it("should be created", function(cb) {
192
            var progress = [];
193
            var cnf = {
194
                identifier: myIdentifier,
195
                passphrase: "password",
196
                keyIndex: 9999
197
            };
198
199
            var expectedVersion = assumedDefault;
200
            if (walletVersion !== null) {
201
                cnf.walletVersion = walletVersion;
202
                expectedVersion = walletVersion;
203
            }
204
205
            client.createNewWallet(cnf, function(err, _wallet, backupInfo) {
0 ignored issues
show
Unused Code introduced by
The parameter backupInfo is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
206
                assert.ifError(err);
207
                assert.ok(_wallet);
208
209
                wallet = _wallet;
210
                assert.equal(wallet.walletVersion, expectedVersion);
211
                assert.equal(wallet.identifier, myIdentifier);
212
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
213
214
                assert.deepEqual(progress, [
215
                    blocktrail.CREATE_WALLET_PROGRESS_START,
216
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_SECRET,
217
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_PRIMARY,
218
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_RECOVERY,
219
                    blocktrail.CREATE_WALLET_PROGRESS_PRIMARY,
220
                    blocktrail.CREATE_WALLET_PROGRESS_BACKUP,
221
                    blocktrail.CREATE_WALLET_PROGRESS_SUBMIT,
222
                    blocktrail.CREATE_WALLET_PROGRESS_INIT,
223
                    blocktrail.CREATE_WALLET_PROGRESS_DONE
224
                ]);
225
226
                cb();
227
            })
228
            .progress(function(p) { progress.push(p); });
229
        });
230
231
        it("should lock", function(cb) {
232
            assert(!wallet.locked);
233
            wallet.lock();
234
            assert(wallet.locked);
235
            cb();
236
        });
237
238
        it("should init", function(cb) {
239
            client.initWallet({
240
                identifier: myIdentifier,
241
                readOnly: true
242
            }, function(err, _wallet) {
243
                assert.ifError(err);
244
                assert.ok(_wallet);
245
246
                wallet = _wallet;
247
248
                cb();
249
            });
250
        });
251
252
        it("should have a 0 balance", function(cb) {
253
            wallet.getBalance(function(err, confirmed, unconfirmed) {
254
                assert.ifError(err);
255
                assert.equal(confirmed, 0);
256
                assert.equal(unconfirmed, 0);
257
258
                cb();
259
            });
260
        });
261
262
        it("shouldn't be able to pay when locked", function(cb) {
263
            wallet.pay({
264
                "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
265
            }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
266
                assert.ok(!!err && err.message.match(/unlocked/));
267
                assert.ok(err instanceof blocktrail.WalletLockedError);
268
269
                cb();
270
            });
271
        });
272
273
        it("shouldn't be able to upgrade when locked", function(cb) {
274
            wallet.upgradeKeyIndex(10000, function(err) {
275
                assert.ok(!!err && err.message.match(/unlocked/));
276
                assert.ok(err instanceof blocktrail.WalletLockedError);
277
278
                cb();
279
            });
280
        });
281
282
        it("should unlock", function(cb) {
283
            wallet.unlock({password: "password"}, function(err) {
284
                assert.ifError(err);
285
286
                cb();
287
            });
288
        });
289
290
        it("should be able to unlock with secret", function(cb) {
291
            var secret = wallet.secret;
292
293
            wallet.lock();
294
            wallet.unlock({secret: secret}, function(err) {
295
                assert.ifError(err);
296
                cb();
297
            });
298
        });
299
300
        it("shouldn't be able to pay when unlocked (because of no balance)", function(cb) {
301
            wallet.pay({
302
                "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
303
            }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
304
                assert.ok(!!err && err.message.match(/balance/));
305
306
                cb();
307
            });
308
        });
309
310
        it("should be able to upgrade when unlocked", function(cb) {
311
            wallet.upgradeKeyIndex(10000, function(err) {
312
                assert.ifError(err);
313
314
                cb();
315
            });
316
        });
317
318
        it("should be able to password change", function(cb) {
319
            wallet.passwordChange("password2", function(err) {
320
                assert.ifError(err);
321
322
                client.initWallet({
323
                    identifier: myIdentifier,
324
                    password: "password2"
325
                }, function(err, _wallet) {
326
                    assert.ifError(err);
327
                    assert.ok(_wallet);
328
329
                    wallet = _wallet;
330
331
                    cb();
332
                });
333
            });
334
        });
335
336
        [
337
            ['', 'string'],
338
            [false, 'string'],
339
            [true, 'boolean']
340
        ].map(function(fixture) {
341
            var invalidInput = fixture[0];
342
            var type = fixture[1];
343
            it('refuses to derive with invalid chain index variable ' + type, function(cb) {
344
                wallet.getNewAddress(invalidInput, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
345
                    assert.ok(!!err && err.message.match(/chain index/));
346
                    cb();
347
                });
348
            });
349
        });
350
    });
351
});
352
353
/**
354
 * Test operations on v2 and v3 wallets.
355
 */
356
[
357
    blocktrail.Wallet.WALLET_VERSION_V1,
358
    blocktrail.Wallet.WALLET_VERSION_V2,
359
    blocktrail.Wallet.WALLET_VERSION_V3
360
].map(function(walletVersion) {
361
    var primarySeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_PASSWORD);
362
363
    describe('test input errors, ' + walletVersion, function() {
364
        it("shouldn't allow primaryPrivateKey in creation", function(cb) {
365
            var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
366
            var primaryPrivateKey = bitcoin.HDNode.fromSeedBuffer(primarySeed, bitcoin.networks.testnet);
367
368
            client.createNewWallet({
369
                identifier: myIdentifier,
370
                passphrase: "password",
371
                primaryPrivateKey: primaryPrivateKey,
372
                walletVersion: walletVersion,
373
                keyIndex: 9999
374
            }, function(err, wallet) {
0 ignored issues
show
Unused Code introduced by
The parameter wallet is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
375
                assert.ok(!!err, "should error");
376
377
                cb();
378
            });
379
        });
380
381
        it("shouldn't allow unlocking with primaryPrivateKey", function(cb) {
382
            client.createNewWallet({
383
                identifier: "unittest-transaction-inputerr-" + walletVersion,
384
                primarySeed: primarySeed,
385
                walletVersion: walletVersion,
386
                keyIndex: 9999
387
            }).then(function(r) {
388
                var wallet = r[0];
389
                wallet.lock();
390
                return wallet;
391
            }, function(err) {
392
                assert.ok(err.message.match(/already exists/));
393
394
                return client.initWallet({
395
                    identifier: "unittest-transaction-inputerr-" + walletVersion,
396
                    readOnly: true
397
                });
398
            }).then(function(wallet) {
399
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
400
401
                return wallet.unlock({primaryPrivateKey: bitcoin.HDNode.fromSeedBuffer(primarySeed, bitcoin.networks.testnet)})
402
                    .then(function() {
403
                        return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
404
                    }, function(err) {
405
                        return err;
406
                    });
407
            })
408
                .then(function(err) {
409
                    assert.ok(!!err, "should error");
410
                    cb();
411
                })
412
                .done();
413
        });
414
    });
415
});
416
417
/**
418
 * Test upgrade to V3 from V1 and V2
419
 */
420
[
421
    blocktrail.Wallet.WALLET_VERSION_V1,
422
    blocktrail.Wallet.WALLET_VERSION_V2
423
].map(function(walletVersion) {
424
    describe("upgrade to V3 from " + walletVersion, function() {
425
        var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
426
        var passphrase = "password";
427
        var wallet;
428
429
        after(function(cb) {
430
            if (wallet) {
431
                wallet.deleteWallet(true, function(err, result) {
432
                    console.log(err, result);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
433
                    cb();
434
                });
435
            } else {
436
                cb();
437
            }
438
        });
439
440
        it("can upgrade", function() {
441
            var addr;
442
            return client.createNewWallet({
443
                identifier: myIdentifier,
444
                passphrase: passphrase,
445
                walletVersion: walletVersion,
446
                keyIndex: 9999
447
            })
448
                .then(function(r) {
449
                    return r[0];
450
                })
451
                .then(function(_wallet) {
452
                    wallet = _wallet;
453
                    addr = wallet.getAddressByPath("M/9999'/0/0");
454
455
                    return wallet;
456
                })
457
                .then(function(wallet) {
458
                    var progress = [];
459
460
                    return wallet.upgradeToV3(passphrase)
461
                        .progress(function(p) {
462
                            progress.push(p);
463
                        })
464
                        .then(function() {
465
                            assert(progress.length);
466
                            return wallet;
467
                        });
468
                })
469
                .then(function(wallet) {
470
                    assert.equal(addr, wallet.getAddressByPath("M/9999'/0/0"));
471
                });
472
        });
473
474
        it("can unlock with secret", function() {
475
            var secret = wallet.secret;
476
            wallet.lock();
477
            return wallet.unlock({secret: secret});
478
        });
479
480
        it("can init after upgrade", function() {
481
            return client.initWallet({
482
                identifier: myIdentifier,
483
                passphrase: passphrase,
484
                keyIndex: 9999
485
            });
486
        });
487
    });
488
});
489
490
describe('test new blank wallet, v1', function() {
491
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
492
    var wallet;
493
494
    after(function(cb) {
495
        if (wallet) {
496
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
497
                cb();
498
            });
499
        } else {
500
            cb();
501
        }
502
    });
503
504
    it("shouldn't already exist", function(cb) {
505
        client.initWallet({
506
            identifier: myIdentifier,
507
            readOnly: true
508
        }, function(err, wallet) {
509
            assert.ok(err);
510
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
511
512
            cb();
513
        });
514
    });
515
516
    it("should be created", function(cb) {
517
        var progress = [];
518
519
        client.createNewWallet({
520
                identifier: myIdentifier,
521
                passphrase: "password",
522
                keyIndex: 9999,
523
                walletVersion: blocktrail.Wallet.WALLET_VERSION_V1
524
            }, function(err, _wallet) {
525
                assert.ifError(err);
526
                assert.ok(_wallet);
527
528
                wallet = _wallet;
529
530
                assert.equal(wallet.identifier, myIdentifier);
531
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
532
533
                assert.deepEqual(progress, [
534
                    blocktrail.CREATE_WALLET_PROGRESS_START,
535
                    blocktrail.CREATE_WALLET_PROGRESS_PRIMARY,
536
                    blocktrail.CREATE_WALLET_PROGRESS_BACKUP,
537
                    blocktrail.CREATE_WALLET_PROGRESS_SUBMIT,
538
                    blocktrail.CREATE_WALLET_PROGRESS_INIT,
539
                    blocktrail.CREATE_WALLET_PROGRESS_DONE
540
                ]);
541
542
                cb();
543
            }
544
        ).progress(function(p) { progress.push(p); });
545
    });
546
547
    it("should lock", function(cb) {
548
        assert(!wallet.locked);
549
        wallet.lock();
550
        assert(wallet.locked);
551
        cb();
552
    });
553
554
    it("should init", function(cb) {
555
        client.initWallet({
556
            identifier: myIdentifier,
557
            readOnly: true
558
        }, function(err, _wallet) {
559
            assert.ifError(err);
560
            assert.ok(_wallet);
561
            assert.equal(wallet.walletVersion, 'v1');
562
563
            wallet = _wallet;
564
565
            cb();
566
        });
567
    });
568
569
    it("should have a 0 balance", function(cb) {
570
        wallet.getBalance(function(err, confirmed, unconfirmed) {
571
            assert.ifError(err);
572
            assert.equal(confirmed, 0);
573
            assert.equal(unconfirmed, 0);
574
575
            cb();
576
        });
577
    });
578
579
    it("should unlock", function(cb) {
580
        wallet.unlock({password: "password"}, function(err) {
581
            assert.ifError(err);
582
583
            cb();
584
        });
585
    });
586
587
    it("shouldn't be able to password change", function(cb) {
588
        wallet.passwordChange("password2", function(err) {
589
            assert.ok(!!err && err.message.match(/version does not support/));
590
591
            cb();
592
        });
593
    });
594
});
595
596
describe('test new blank wallet, old syntax', function() {
597
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
598
    var wallet;
599
600
    after(function(cb) {
601
        if (wallet) {
602
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
603
                cb();
604
            });
605
        } else {
606
            cb();
607
        }
608
    });
609
610
    it("shouldn't already exist", function(cb) {
611
        client.initWallet(myIdentifier, "password", function(err, wallet) {
612
            assert.ok(err);
613
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
614
615
            cb();
616
        });
617
    });
618
619
    it("should be created", function(cb) {
620
        client.createNewWallet(myIdentifier, "password", 9999, function(err, _wallet) {
621
            assert.ifError(err);
622
            assert.ok(_wallet);
623
624
            wallet = _wallet;
625
626
            assert.equal(wallet.identifier, myIdentifier);
627
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
628
            cb();
629
        });
630
    });
631
632
    it("should have a 0 balance", function(cb) {
633
        wallet.getBalance(function(err, confirmed, unconfirmed) {
634
            assert.ifError(err);
635
            assert.equal(confirmed, 0);
636
            assert.equal(unconfirmed, 0);
637
638
            cb();
639
        });
640
    });
641
642
    it("shouldn't be able to pay", function(cb) {
643
        wallet.pay({
644
            "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
645
        }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
646
            assert.ok(!!err);
647
648
            cb();
649
        });
650
    });
651
});
652
653
describe('test new wallet, without mnemonics', function() {
654
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
655
    var wallet;
656
657
    var primarySeed = bip39.mnemonicToSeed(bip39.generateMnemonic(512), "password");
658
    var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(bip39.mnemonicToSeed(bip39.generateMnemonic(512), ""), bitcoin.networks.testnet);
659
    var backupPublicKey = backupPrivateKey.neutered();
660
661
    after(function(cb) {
662
        if (wallet) {
663
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
664
                cb();
665
            });
666
        } else {
667
            cb();
668
        }
669
    });
670
671
    it("shouldn't already exist", function(cb) {
672
        client.initWallet({
673
            identifier: myIdentifier
674
        }, function(err, wallet) {
675
            assert.ok(err);
676
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
677
678
            cb();
679
        });
680
    });
681
682
    it("should be created", function(cb) {
683
        client.createNewWallet({
684
                identifier: myIdentifier,
685
                primarySeed: primarySeed,
686
                backupPublicKey: backupPublicKey,
687
                keyIndex: 9999
688
            }, function(err, _wallet) {
689
                assert.ifError(err);
690
                assert.ok(_wallet);
691
                assert.ok(!_wallet.isSegwit());
692
                assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
693
694
                wallet = _wallet;
695
696
                assert.equal(wallet.identifier, myIdentifier);
697
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
698
                cb();
699
            }
700
        );
701
    });
702
703
    it("should be initializable", function(cb) {
704
        client.initWallet({
705
                identifier: myIdentifier,
706
                primarySeed: primarySeed,
707
                keyIndex: 9999
708
            }, function(err, _wallet) {
709
                assert.ifError(err);
710
                assert.ok(_wallet);
711
                assert.ok(!_wallet.isSegwit());
712
                assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
713
714
                wallet = _wallet;
715
716
                cb();
717
            }
718
        );
719
    });
720
721
    it("should have a 0 balance", function(cb) {
722
        wallet.getBalance(function(err, confirmed, unconfirmed) {
723
            assert.ifError(err);
724
            assert.equal(confirmed, 0);
725
            assert.equal(unconfirmed, 0);
726
727
            cb();
728
        });
729
    });
730
731
    it("shouldn't be able to pay", function(cb) {
732
        wallet.pay({
733
            "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
734
        }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
735
            assert.ok(!!err);
736
737
            cb();
738
        });
739
    });
740
});
741
742
describe('test wallet, do transaction', function() {
743
    var wallet;
744
745
    it("should exists", function(cb) {
746
        client.initWallet({
747
            identifier: "unittest-transaction",
748
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
749
        }, function(err, _wallet) {
750
            assert.ifError(err);
751
            assert.ok(_wallet);
752
            assert.ok(!_wallet.isSegwit());
753
            assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
754
            wallet = _wallet;
755
756
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
757
            assert.equal(wallet.identifier, "unittest-transaction");
758
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
759
            cb();
760
        });
761
    });
762
763
    it("should have the expected addresses", function(cb) {
764
        assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD");
765
        assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2MynrezSyqCq1x5dMPtRDupTPA4sfVrNBKq");
766
        assert.equal(wallet.getAddressByPath("M/9999'/0/44"), "2N5eqrZE7LcfRyCWqpeh1T1YpMdgrq8HWzh");
767
768
        cb();
769
    });
770
771
    it("should have a balance", function(cb) {
772
        this.timeout(0);
773
774
        wallet.getBalance(function(err, confirmed, unconfirmed) {
775
            assert.ok(confirmed + unconfirmed > 0);
776
            assert.ok(confirmed > 0);
777
778
            cb();
779
        });
780
    });
781
782
    it("should return errors when expected", function(cb) {
783
        async.parallel([
784
            function(cb) {
785
                wallet.pay({"": blocktrail.toSatoshi(0.001)}, function(err) {
786
                    assert.ok(!!err);
787
                    assert.equal(err.message, "Invalid address [] (Invalid checksum)");
788
                    assert.ok(err instanceof blocktrail.InvalidAddressError);
789
790
                    cb();
791
                });
792
            },
793
            function(cb) {
794
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHA": blocktrail.toSatoshi(0.001)}, function(err) {
795
                    assert.ok(!!err);
796
                    assert.equal(err.message, "Invalid address [2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHA] (Invalid checksum)");
797
                    assert.ok(err instanceof blocktrail.InvalidAddressError);
798
799
                    cb();
800
                });
801
            },
802
            function(cb) {
803
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 1}, function(err) {
804
                    assert.ok(!!err);
805
                    assert.equal(err.message, "Values should be more than dust (" + blocktrail.DUST + ")");
806
                    assert.ok(err instanceof blocktrail.WalletSendError);
807
808
                    cb();
809
                });
810
            },
811
            function(cb) {
812
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 0}, function(err) {
813
                    assert.ok(!!err);
814
                    assert.equal(err.message, "Values should be non zero");
815
                    assert.ok(err instanceof blocktrail.WalletSendError);
816
817
                    cb();
818
                });
819
            },
820
            function(cb) {
821
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 1.1}, function(err) {
822
                    assert.ok(!!err);
823
                    assert.equal(err.message, "Values should be in Satoshis");
824
                    assert.ok(err instanceof blocktrail.WalletSendError);
825
826
                    cb();
827
                });
828
            }
829
        ], cb);
830
    });
831
832
    it("should be able to build a transaction paying a bech32 address", function(cb) {
833
        var address = "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs";
834
        var wp = "00149bce9399f9eeddad66635d4be171ec8f14decc59";
835
        var pay = {};
836
        pay[address] = blocktrail.toSatoshi(0.001);
837
838
        wallet.buildTransaction(pay, null, false, false, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
839
            assert.ifError(err);
840
            assert.ok(tx);
841
            assert.ok(tx.toHex());
842
            assert.equal(wp, tx.outs[0].script.toString('hex'));
843
            cb();
844
        });
845
    });
846
847
    it("change should be randomized when building a transaction", function(cb) {
848
        wallet.getNewAddress(function(err, address, path) {
849
            assert.ifError(err);
850
            assert.ok(path.indexOf("M/9999'/0/") === 0);
851
            assert.ok(bitcoin.address.fromBase58Check(address));
852
853
            var pay = {};
854
            pay[address] = blocktrail.toSatoshi(0.001);
855
856
            var changeIdxs = [];
857
            var tryX = 10;
858
859
            async.whilst(
860
                function() { return tryX-- > 0 && _.uniq(changeIdxs).length < 2; },
861
                function(cb) {
862
                    wallet.buildTransaction(pay, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
863
                        assert.ifError(err);
864
865
                        tx.outs.forEach(function(output, idx) {
866
                            var addr = bitcoin.address.fromOutputScript(output.script, client.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin);
867
868
                            if (addr !== address) {
869
                                changeIdxs.push(idx);
870
                            }
871
                        });
872
873
                        cb();
874
                    });
875
                },
876
                function() {
877
                    assert(_.uniq(changeIdxs).length > 1);
878
879
                    cb();
880
                }
881
            );
882
        });
883
884
        it("should be able to build a transaction", function(cb) {
0 ignored issues
show
Unused Code introduced by
The parameter cb is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
885
            wallet.getNewAddress(function(err, address, path) {
886
                assert.ifError(err);
887
                assert.ok(path.indexOf("M/9999'/0/") === 0);
888
                assert.ok(bitcoin.address.fromBase58Check(address));
889
890
                var pay = {};
891
                pay[address] = blocktrail.toSatoshi(0.001);
892
893
                wallet.buildTransaction(pay, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
894
                    assert.ifError(err);
895
                    assert.ok(tx);
896
                    assert.ok(tx.toHex());
897
                });
898
            });
899
        });
900
    });
901
902
    it("should be able to do a payment", function(cb) {
903
        wallet.getNewAddress(function(err, address, path) {
904
            assert.ifError(err);
905
            assert.ok(path.indexOf("M/9999'/", wallet.chain, "/") === 0);
906
            assert.ok(bitcoin.address.fromBase58Check(address));
907
908
            var pay = {};
909
            pay[address] = blocktrail.toSatoshi(0.001);
910
911
            var progress = [];
912
913
            wallet.pay(pay, function(err, txHash) {
914
                assert.ifError(err);
915
                assert.ok(txHash);
916
917
                // change address doesn't always happen ...
918
                if (progress.indexOf(blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS) === -1) {
919
                    progress.splice(2, 0, blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS);
920
                }
921
922
                assert.deepEqual(progress, [
923
                    blocktrail.Wallet.PAY_PROGRESS_START,
924
                    blocktrail.Wallet.PAY_PROGRESS_COIN_SELECTION,
925
                    blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS,
926
                    blocktrail.Wallet.PAY_PROGRESS_SIGN,
927
                    blocktrail.Wallet.PAY_PROGRESS_SEND,
928
                    blocktrail.Wallet.PAY_PROGRESS_DONE
929
                ]);
930
931
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
932
                setTimeout(function() {
933
                    client.transaction(txHash, function(err, tx) {
934
                        assert.ifError(err);
935
                        assert.ok(tx);
936
937
                        cb();
938
                    });
939
                }, WAIT_FOR_TX_PROCESSED);
940
            }).progress(function(_progress) {
941
                progress.push(_progress);
942
            });
943
        });
944
    });
945
});
946
947
describe('test wallet with segwit chain', function() {
948
    var wallet;
949
950
    it("should exist and be setup", function(cb) {
951
        client.initWallet({
952
            identifier: "unittest-transaction-sw",
953
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
954
        }, function(err, _wallet) {
955
            assert.ifError(err);
956
            assert.ok(_wallet);
957
            assert.equal(_wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
958
            assert.equal(_wallet.identifier, "unittest-transaction-sw");
959
            assert.equal(_wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
960
            assert.ok(_wallet.isSegwit());
961
            assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
962
            assert.equal(blocktrail.Wallet.CHAIN_BTC_SEGWIT, _wallet.changeChain);
963
964
            wallet = _wallet;
965
            cb();
966
        });
967
    });
968
969
    it("getNewAddress produces plain P2SH addresses", function(cb) {
970
        wallet.getNewAddress(function(err, address, path) {
971
            assert.ifError(err);
972
            assert.ok(path.indexOf("M/9999'/0/") === 0);
973
974
            assert.ok(bitcoin.address.fromBase58Check(address));
975
976
            cb();
977
        });
978
    });
979
980
    it("getNewAddress produces segwit P2SH addresses for change chain", function(cb) {
981
        wallet.getNewAddress(wallet.changeChain, function(err, address, path) {
982
            assert.ifError(err);
983
            assert.ok(path.indexOf("M/9999'/2/") === 0);
984
985
            assert.ok(bitcoin.address.fromBase58Check(address));
986
987
            cb();
988
        });
989
    });
990
991
    it("getWalletScriptByPath produces P2SH addresses, and returns witnessScript", function(cb) {
992
        var eAddress = "2N3j4Vx3D9LPumjtRbRe2RJpwVocvCCkHKh";
993
994
        assert.equal(wallet.getAddressByPath("M/9999'/2/0"), eAddress);
995
996
        var walletScript = wallet.getWalletScriptByPath("M/9999'/2/0");
997
        assert.equal(walletScript.address, eAddress);
998
        assert.ok(walletScript.witnessScript);
999
        assert.ok(walletScript.redeemScript);
1000
        cb();
1001
    });
1002
});
1003
1004
describe('test wallet, do transaction, segwit spend', function() {
1005
    var wallets = [];
1006
    after(function(cb) {
1007
        if (wallets.length > 0) {
1008
            wallets.map(function(wallet) {
1009
                wallet.deleteWallet(true);
1010
            });
1011
        }
1012
        cb();
1013
    });
1014
1015
    var unitTestWallet;
1016
    var identifier = crypto.randomBytes(12).toString('hex');
1017
    var segwitWallet;
1018
    var receiveAddr;
1019
    var receiveBackAddr;
1020
    it("should setup the funding wallet", function(cb) {
1021
        client.initWallet({
1022
            identifier: "unittest-transaction",
1023
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1024
        }, function(err, _wallet) {
1025
            assert.ifError(err);
1026
            assert.ok(_wallet);
1027
1028
            _wallet.getNewAddress(function(err, address, path) {
1029
                assert.ifError(err);
1030
                assert.ok(address);
1031
                assert.ok(path);
1032
1033
                unitTestWallet = _wallet;
1034
                receiveBackAddr = address;
1035
                cb();
1036
            });
1037
        });
1038
    });
1039
1040
    it("should make the receiving segwit wallet", function(cb) {
1041
        createTransactionTestWallet(identifier, true, function(err, newWallet) {
1042
            wallets.push(newWallet);
1043
            assert.ifError(err);
1044
            newWallet.getNewAddress(newWallet.changeChain, function(err, address, path) {
1045
                assert.ifError(err);
1046
                assert.ok(bitcoin.address.fromBase58Check(address));
1047
                assert.ok(newWallet.isSegwit());
1048
                assert.ok(path.indexOf("M/9999'/2/") === 0);
1049
1050
                var checkScript = newWallet.getWalletScriptByPath(path);
1051
                assert.ok(checkScript.address = address);
1052
                assert.ok(checkScript.redeemScript instanceof Buffer);
0 ignored issues
show
Bug introduced by
The variable Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
1053
                assert.ok(checkScript.witnessScript instanceof Buffer);
1054
1055
                segwitWallet = newWallet;
1056
                receiveAddr = address;
1057
                cb();
1058
            });
1059
        });
1060
    });
1061
1062
    var paymentHash;
1063
    it("should receive funds from unitTestWallet", function(cb) {
1064
        var pay = {};
1065
        pay[receiveAddr] = 30000;
1066
        unitTestWallet.pay(pay, null, true, function(err, txid) {
1067
            assert.ifError(err);
1068
            assert.ok(txid);
1069
            paymentHash = txid;
0 ignored issues
show
Unused Code introduced by
The variable paymentHash seems to be never used. Consider removing it.
Loading history...
1070
            cb();
1071
        });
1072
    });
1073
1074
    it("should return to unitTestWallet", function(cb) {
1075
        var pay = {};
1076
        pay[receiveBackAddr] = 20000;
1077
        segwitWallet.pay(pay, null, true, function(err, txid) {
1078
            assert.ifError(err);
1079
            assert.ok(txid);
1080
1081
            setTimeout(function() {
1082
                client.transaction(txid, function(err, tx) {
1083
                    assert.ifError(err);
1084
                    assert.ok(tx);
1085
                    cb();
1086
                });
1087
            }, WAIT_FOR_TX_PROCESSED);
1088
        });
1089
    });
1090
});
1091
describe('test wallet, do transaction, without mnemonics', function() {
1092
    var wallet;
1093
1094
    var primarySeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_PASSWORD);
1095
1096
    it("should exists", function(cb) {
1097
        client.initWallet({
1098
                identifier: "unittest-transaction",
1099
                primarySeed: primarySeed,
1100
                primaryMnemonic: false // explicitly set false because we're reusing unittest-transaction which has a mnemonic stored
1101
            }, function(err, _wallet) {
1102
                assert.ifError(err);
1103
                assert.ok(_wallet);
1104
1105
                wallet = _wallet;
1106
1107
                assert.equal(wallet.identifier, "unittest-transaction");
1108
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1109
                cb();
1110
            }
1111
        );
1112
    });
1113
1114
    it("should have the expected addresses", function(cb) {
1115
        assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD");
1116
        assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2MynrezSyqCq1x5dMPtRDupTPA4sfVrNBKq");
1117
        assert.equal(wallet.getAddressByPath("M/9999'/0/44"), "2N5eqrZE7LcfRyCWqpeh1T1YpMdgrq8HWzh");
1118
1119
        cb();
1120
    });
1121
1122
    it("should have a balance", function(cb) {
1123
        this.timeout(0);
1124
1125
        wallet.getBalance(function(err, confirmed, unconfirmed) {
1126
            assert.ok(confirmed + unconfirmed > 0);
1127
            assert.ok(confirmed > 0);
1128
1129
            cb();
1130
        });
1131
    });
1132
1133
    it("should be able to do a payment", function(cb) {
1134
        wallet.getNewAddress(function(err, address, path) {
1135
            assert.ifError(err);
1136
            assert.ok(path.indexOf("M/9999'/0/") === 0);
1137
            assert.ok(bitcoin.address.fromBase58Check(address));
1138
1139
            var pay = {};
1140
            pay[address] = blocktrail.toSatoshi(0.001);
1141
1142
            wallet.pay(pay, function(err, txHash) {
1143
                assert.ifError(err);
1144
                assert.ok(txHash);
1145
1146
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1147
                setTimeout(function() {
1148
                    client.transaction(txHash, function(err, tx) {
1149
                        assert.ifError(err);
1150
                        assert.ok(tx);
1151
1152
                        cb();
1153
                    });
1154
                }, WAIT_FOR_TX_PROCESSED);
1155
            });
1156
        });
1157
    });
1158
});
1159
1160
describe('test wallet, do opreturn transaction', function() {
1161
    var wallet;
1162
1163
    it("should exists", function(cb) {
1164
        client.initWallet({
1165
            identifier: "unittest-transaction",
1166
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1167
        }, function(err, _wallet) {
1168
            assert.ifError(err);
1169
            assert.ok(_wallet);
1170
1171
            wallet = _wallet;
1172
1173
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1174
            assert.equal(wallet.identifier, "unittest-transaction");
1175
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1176
            cb();
1177
        });
1178
    });
1179
1180
    it("should be able to do a payment with opreturn output", function(cb) {
1181
        wallet.getNewAddress(function(err, address, path) {
0 ignored issues
show
Unused Code introduced by
The parameter path is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1182
            assert.ifError(err);
1183
1184
            var pay = {};
1185
            pay[address] = blocktrail.toSatoshi(0.001);
1186
            pay[blocktrail.Wallet.OP_RETURN] = "BLOCKTRAILTESTDATA";
1187
1188
            wallet.pay(pay, function(err, txHash) {
1189
                assert.ifError(err);
1190
                assert.ok(txHash);
1191
1192
1193
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1194
                setTimeout(function() {
1195
                    client.transaction(txHash, function(err, tx) {
1196
                        assert.ifError(err);
1197
                        assert.ok(tx);
1198
1199
                        var hasOpreturn;
1200
                        tx.outputs.forEach(function(output) {
1201
                            if (output.type === 'op_return') {
1202
                                hasOpreturn = true;
1203
1204
                                assert.equal(output.script_hex, "6a12424c4f434b545241494c5445535444415441");
1205
                            }
1206
                        });
1207
                        assert.ok(hasOpreturn);
1208
1209
                        cb();
1210
                    });
1211
                }, WAIT_FOR_TX_PROCESSED);
1212
            });
1213
        });
1214
    });
1215
});
1216
1217
describe('test wallet, do forcefee transaction', function() {
1218
    var wallet;
1219
1220
    it("should exists", function(cb) {
1221
        client.initWallet({
1222
            identifier: "unittest-transaction",
1223
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1224
        }, function(err, _wallet) {
1225
            assert.ifError(err);
1226
            assert.ok(_wallet);
1227
1228
            wallet = _wallet;
1229
1230
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1231
            assert.equal(wallet.identifier, "unittest-transaction");
1232
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1233
            cb();
1234
        });
1235
    });
1236
1237
    it("should be able to do a payment with forced fee", function(cb) {
1238
        wallet.getNewAddress(function(err, address, path) {
0 ignored issues
show
Unused Code introduced by
The parameter path is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1239
            assert.ifError(err);
1240
1241
            var pay = {};
1242
            pay[address] = blocktrail.toSatoshi(0.01);
1243
            var forceFee = blocktrail.toSatoshi(0.00054321);
1244
1245
            wallet.pay(pay, null, false, true, blocktrail.Wallet.FEE_STRATEGY_FORCE_FEE, null, {
1246
                forcefee: forceFee,
1247
                checkFee: false
1248
            }, function(err, txHash) {
1249
                assert.ifError(err);
1250
                assert.ok(txHash);
1251
1252
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1253
                setTimeout(function() {
1254
                    client.transaction(txHash, function(err, tx) {
1255
                        assert.ifError(err);
1256
                        // this could very occasionally fail if change < DUST because then it's added to fee, so adjusted check for that
1257
                        assert.ok(tx['total_fee'] >= forceFee && tx['total_fee'] <= forceFee + blocktrail.DUST,
1258
                            "fee [" + tx['total_fee'] + "] should be equal to forced fee [" +  forceFee + "] for tx [" + txHash + "]");
1259
1260
                        cb();
1261
                    });
1262
                }, WAIT_FOR_TX_PROCESSED);
1263
            });
1264
        });
1265
    });
1266
});
1267
1268
describe('test wallet discovery and upgrade key index', function() {
1269
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1270
    var wallet;
1271
1272
    after(function(cb) {
1273
        if (wallet) {
1274
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1275
                cb();
1276
            });
1277
        } else {
1278
            cb();
1279
        }
1280
    });
1281
1282
    it("should be created", function(cb) {
1283
        createDiscoveryTestWallet(myIdentifier, "password", function(err, _wallet) {
1284
            assert.ifError(err);
1285
            assert.ok(_wallet);
1286
            _wallet.chain = blocktrail.Wallet.CHAIN_BTC_DEFAULT;
1287
            wallet = _wallet;
1288
1289
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole kingdom");
1290
            assert.equal(wallet.identifier, myIdentifier);
1291
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1292
1293
            cb();
1294
        });
1295
    });
1296
1297
    it("should have the expected addresses", function(cb) {
1298
        async.series([
1299
            function(cb) {
1300
                wallet.getNewAddress(function(err, address, path) {
1301
                    assert.ifError(err);
1302
                    assert.equal(path, "M/9999'/0/0");
1303
                    assert.equal(address, "2Mtfn5S9tVWnnHsBQixCLTsCAPFHvfhu6bM");
1304
1305
                    cb();
1306
                });
1307
            },
1308
            function(cb) {
1309
                wallet.getNewAddress(function(err, address, path) {
1310
                    assert.ifError(err);
1311
                    assert.equal(path, "M/9999'/0/1");
1312
                    assert.equal(address, "2NG49GDkm5qCYvDFi4cxAnkSho8qLbEz6C4");
1313
1314
                    cb();
1315
                });
1316
            },
1317
            function(cb) {
1318
                assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2NG49GDkm5qCYvDFi4cxAnkSho8qLbEz6C4");
1319
                assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2N1kM5xeDaCN9Weog3mbyxjpryNZcirnkB7");
1320
1321
                cb();
1322
            }
1323
        ], cb);
1324
    });
1325
1326
    it("should have a balance after discovery", function(cb) {
1327
        this.timeout(0);
1328
1329
        wallet.doDiscovery(50, function(err, confirmed, unconfirmed) {
1330
            assert.ok(confirmed + unconfirmed > 0);
1331
1332
            cb();
1333
        });
1334
    });
1335
1336
    it("should be upgraded and have expected addresses", function(cb) {
1337
        // set upgrade
1338
        wallet.upgradeToKeyIndex = 10000;
1339
        // lock
1340
        wallet.lock();
1341
        // unlock should upgrade
1342
        wallet.unlock({
1343
            passphrase: "password"
1344
        }).then(function() {
1345
            assert.equal(wallet.getBlocktrailPublicKey("M/10000'").toBase58(), "tpubD9m9hziKhYQExWgzMUNXdYMNUtourv96sjTUS9jJKdo3EDJAnCBJooMPm6vGSmkNTNAmVt988dzNfNY12YYzk9E6PkA7JbxYeZBFy4XAaCp");
1346
1347
            assert.equal(wallet.getAddressByPath("M/10000'/0/0"), "2N9ZLKXgs12JQKXvLkngn7u9tsYaQ5kXJmk");
1348
1349
            wallet.getNewAddress(function(err, address, path) {
1350
                assert.ifError(err);
1351
                assert.equal(path, "M/10000'/0/0");
1352
                assert.equal(address, "2N9ZLKXgs12JQKXvLkngn7u9tsYaQ5kXJmk");
1353
1354
                cb();
1355
            });
1356
        });
1357
    });
1358
});
1359
1360
describe('test wallet with bad password', function() {
1361
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1362
    var wallet;
1363
1364
    after(function(cb) {
1365
        if (wallet) {
1366
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1367
                cb();
1368
            });
1369
        } else {
1370
            cb();
1371
        }
1372
    });
1373
1374
    it("should be created", function(cb) {
1375
        createDiscoveryTestWallet(myIdentifier, "badpassword", function(err, _wallet) {
1376
            assert.ifError(err);
1377
            assert.ok(_wallet);
1378
1379
            _wallet.chain = blocktrail.Wallet.CHAIN_BTC_DEFAULT;
1380
            wallet = _wallet;
1381
1382
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole kingdom");
1383
            assert.equal(wallet.identifier, myIdentifier);
1384
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1385
1386
            cb();
1387
        });
1388
    });
1389
1390
    it("should have the expected addresses (different from with the correct password)", function(cb) {
1391
        async.series([
1392
            function(cb) {
1393
                wallet.getNewAddress(function(err, address, path) {
1394
                    assert.ifError(err);
1395
                    assert.equal(path, "M/9999'/0/0");
1396
                    assert.equal(address, "2N9SGrV4NKRjdACYvHLPpy2oiPrxTPd44rg");
1397
1398
                    cb();
1399
                });
1400
            },
1401
            function(cb) {
1402
                wallet.getNewAddress(function(err, address, path) {
1403
                    assert.ifError(err);
1404
                    assert.equal(path, "M/9999'/0/1");
1405
                    assert.equal(address, "2NDq3DRy9E3YgHDA3haPJj3FtUS6V93avkf");
1406
1407
                    cb();
1408
                });
1409
            }
1410
        ], cb);
1411
    });
1412
1413
    it("shouldn't have a balance after discovery", function(cb) {
1414
        this.timeout(0);
1415
1416
        wallet.doDiscovery(50, function(err, confirmed, unconfirmed) {
1417
            assert.ok(confirmed + unconfirmed === 0);
1418
1419
            cb();
1420
        });
1421
    });
1422
});
1423
1424
describe('test wallet webhook', function() {
1425
    // this.timeout(0); // disable, can take long
1426
1427
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1428
    var wallet;
1429
1430
    after(function(cb) {
1431
        if (wallet) {
1432
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1433
                cb();
1434
            });
1435
        } else {
1436
            cb();
1437
        }
1438
    });
1439
1440
    it("shouldn't already exist", function(cb) {
1441
        client.initWallet({
1442
            identifier: myIdentifier,
1443
            passphrase: "password"
1444
        }, function(err, wallet) {
1445
            assert.ok(err);
1446
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
1447
1448
            cb();
1449
        });
1450
    });
1451
1452
    it("should be created", function(cb) {
1453
        client.createNewWallet({
1454
            identifier: myIdentifier,
1455
            passphrase: "password",
1456
            keyIndex: 9999
1457
        }, function(err, _wallet) {
1458
            assert.ifError(err);
1459
            assert.ok(_wallet);
1460
1461
            wallet = _wallet;
1462
1463
            assert.equal(wallet.identifier, myIdentifier);
1464
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1465
            cb();
1466
        });
1467
    });
1468
1469
    it("should have a 0 balance", function(cb) {
1470
        wallet.getBalance(function(err, confirmed, unconfirmed) {
1471
            assert.ifError(err);
1472
            assert.equal(confirmed, 0);
1473
            assert.equal(unconfirmed, 0);
1474
1475
            cb();
1476
        });
1477
    });
1478
1479
    it("should be able to create a webhook", function(cb) {
1480
        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", function(err, webhook) {
1481
            assert.ifError(err);
1482
            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1483
            assert.equal(webhook['identifier'], "WALLET-" + myIdentifier);
1484
1485
            wallet.deleteWebhook(function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1486
                assert.ifError(err);
1487
1488
                cb();
1489
            });
1490
        });
1491
    });
1492
1493
    it("should be able to create a webhook with custom identifier", function(cb) {
1494
        var myWebhookIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1495
1496
        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", myWebhookIdentifier, function(err, webhook) {
1497
            assert.ifError(err);
1498
            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1499
            assert.equal(webhook['identifier'], myWebhookIdentifier);
1500
1501
            client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1502
                assert.ifError(err);
1503
1504
                wallet.getNewAddress(function(err, address1) {
1505
                    assert.ifError(err);
1506
1507
                    wallet.deleteWebhook(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1508
                        assert.ifError(err);
1509
1510
                        var myWebhookIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1511
1512
                        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", myWebhookIdentifier, function(err, webhook) {
1513
                            assert.ifError(err);
1514
                            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1515
                            assert.equal(webhook['identifier'], myWebhookIdentifier);
1516
1517
                            client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
1518
                                assert.ifError(err);
1519
                                assert.ok(_.includes(_.map(result['data'], 'address'), address1));
1520
1521
                                wallet.getNewAddress(function(err, address2) {
1522
                                    assert.ifError(err);
1523
1524
                                    client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
1525
                                        assert.ifError(err);
1526
                                        assert.ok(_.includes(_.map(result['data'], 'address'), address2));
1527
1528
                                        wallet.deleteWallet(function(err, result) {
1529
                                            assert.ifError(err);
1530
                                            assert.ok(result);
1531
1532
                                            client.deleteWebhook(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1533
                                                assert.ok(err);
1534
1535
                                                cb();
1536
                                            });
1537
                                        });
1538
                                    });
1539
                                });
1540
                            });
1541
                        });
1542
                    });
1543
1544
                });
1545
            });
1546
        });
1547
    });
1548
});
1549
1550
describe("Wallet.getAddressAndType", function() {
1551
    var fixtures = [
1552
        {
1553
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1554
            network: bitcoin.networks.testnet,
1555
            type: "bech32",
1556
            valid: true
1557
        },
1558
        {
1559
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1560
            network: bitcoin.networks.testnet,
1561
            type: "bech32",
1562
            valid: true
1563
        },
1564
        {
1565
            address: "muinVykhtZyonxQxk8zBptX6Lmri91bdNG",
1566
            network: bitcoin.networks.testnet,
1567
            type: "base58",
1568
            valid: true
1569
        },
1570
        {
1571
            address: "2N7T4CD6CEuNHJoGKpoJH3YexqektXjyy6L",
1572
            network: bitcoin.networks.testnet,
1573
            type: "base58",
1574
            valid: true
1575
        },
1576
        {
1577
            address: "16uf9UUBbUHdVAnETGZQnvXZcf9NPU1QR6",
1578
            network: bitcoin.networks.bitcoin,
1579
            type: "base58",
1580
            valid: true
1581
        },
1582
        {
1583
            address: "3CgSFohdEqd7pSxbDAJeJo6X5Qm2tBbby9",
1584
            network: bitcoin.networks.bitcoin,
1585
            type: "base58",
1586
            valid: true
1587
        },
1588
        {
1589
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1590
            network: bitcoin.networks.bitcoin,
1591
            type: "bech32",
1592
            valid: true
1593
        },
1594
        {
1595
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1596
            network: bitcoin.networks.bitcoin,
1597
            type: "bech32",
1598
            valid: true
1599
        },
1600
        {
1601
            address: "16uf9UUBbUHdVAnETGZQnvXZcf9NPU1QR6",
1602
            network: bitcoin.networks.testnet,
1603
            type: "base58",
1604
            error: "Address invalid on this network",
1605
            valid: false
1606
        },
1607
        {
1608
            address: "3CgSFohdEqd7pSxbDAJeJo6X5Qm2tBbby9",
1609
            network: bitcoin.networks.testnet,
1610
            type: "base58",
1611
            error: "Address invalid on this network",
1612
            valid: false
1613
        },
1614
        {
1615
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1616
            network: bitcoin.networks.testnet,
1617
            type: "bech32",
1618
            error: "Address invalid on this network",
1619
            valid: false
1620
        },
1621
        {
1622
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1623
            network: bitcoin.networks.testnet,
1624
            type: "bech32",
1625
            error: "Address invalid on this network",
1626
            valid: false
1627
        },
1628
        {
1629
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1630
            network: bitcoin.networks.bitcoincash,
1631
            error: "Non-base58 character",
1632
            type: "bech32",
1633
            valid: false
1634
        },
1635
        {
1636
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1637
            network: bitcoin.networks.bitcoincash,
1638
            error: "Non-base58 character",
1639
            type: "bech32",
1640
            valid: false
1641
        },
1642
        {
1643
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1644
            network: bitcoin.networks.bitcoincashtestnet,
1645
            error: "Non-base58 character",
1646
            type: "bech32",
1647
            valid: false
1648
        },
1649
        {
1650
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1651
            network: bitcoin.networks.bitcoincashtestnet,
1652
            error: "Non-base58 character",
1653
            type: "bech32",
1654
            valid: false
1655
        },
1656
        {
1657
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1658
            network: bitcoin.networks.bitcoin,
1659
            error: "Address invalid on this network",
1660
            type: "bech32",
1661
            valid: false
1662
        },
1663
        {
1664
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1665
            network: bitcoin.networks.bitcoin,
1666
            error: "Address invalid on this network",
1667
            type: "bech32",
1668
            valid: false
1669
        },
1670
        {
1671
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1672
            network: bitcoin.networks.testnet,
1673
            error: "Address invalid on this network",
1674
            type: "bech32",
1675
            valid: false
1676
        },
1677
        {
1678
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1679
            network: bitcoin.networks.testnet,
1680
            error: "Address invalid on this network",
1681
            type: "bech32",
1682
            valid: false
1683
        }
1684
    ];
1685
1686
    fixtures.map(function(fixture) {
1687
        var description =
1688
            (fixture.valid ? "parses" : "fails to parse") +
1689
            " a " + fixture.type + " address: " + fixture.address;
1690
1691
        it(description, function(cb) {
1692
            var addrAndType;
1693
            var err;
1694
            try {
1695
                addrAndType = Wallet.getAddressAndType(fixture.address, fixture.network);
1696
            } catch (e) {
1697
                err = e;
1698
            }
1699
1700
            if (fixture.valid) {
1701
                assert.ifError(err);
0 ignored issues
show
Bug introduced by
The variable err seems to not be initialized for all possible execution paths. Are you sure ifError handles undefined variables?
Loading history...
1702
                assert.ok(Object.keys(addrAndType).indexOf("address") !== -1);
1703
                assert.ok(Object.keys(addrAndType).indexOf("decoded") !== -1);
1704
                assert.ok(Object.keys(addrAndType).indexOf("type") !== -1);
1705
                assert.equal(addrAndType.type, fixture.type);
1706
                assert.equal(addrAndType.address, fixture.address);
1707
            } else {
1708
                assert.ok(typeof err === "object");
1709
                assert.ok(typeof addrAndType === "undefined");
1710
                if (Object.keys(fixture).indexOf("error") !== -1) {
1711
                    assert.equal(err.message, fixture.error);
1712
                }
1713
            }
1714
            cb();
1715
        });
1716
    });
1717
});
1718
1719
describe("Wallet.convertPayToOutputs", function() {
1720
    var network = bitcoin.networks.testnet;
1721
    var fixtures = [
1722
        {
1723
            description: "p2wpkh",
1724
            network: bitcoin.networks.testnet,
1725
            value: 12345,
1726
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1727
            script: "00149bce9399f9eeddad66635d4be171ec8f14decc59"
1728
        },
1729
        {
1730
            description: "p2wsh",
1731
            network: bitcoin.networks.testnet,
1732
            value: 12345,
1733
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1734
            script: "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262"
1735
        },
1736
        {
1737
            description: "p2pkh",
1738
            network: bitcoin.networks.testnet,
1739
            value: 12345,
1740
            address: "muinVykhtZyonxQxk8zBptX6Lmri91bdNG",
1741
            script: "76a9149bce9399f9eeddad66635d4be171ec8f14decc5988ac"
1742
        },
1743
        {
1744
            description: "p2sh",
1745
            network: bitcoin.networks.testnet,
1746
            value: 12345,
1747
            address: "2N7T4CD6CEuNHJoGKpoJH3YexqektXjyy6L",
1748
            script: "a9149bce9399f9eeddad66635d4be171ec8f14decc5987"
1749
        }
1750
    ];
1751
1752
    fixtures.map(function(fixture, i) {
1753
1754
        it(fixture.description + " converted to script, " + i, function(cb) {
1755
            var test = function(outputs) {
1756
                assert.ok(Array.isArray(outputs));
1757
                assert.equal(outputs[0].value, fixture.value);
1758
                assert.equal(outputs[0].scriptPubKey, fixture.script);
1759
                assert.equal(outputs[0].address, null);
1760
            };
1761
1762
            // should accept some input of ours
1763
            var pay = [{
1764
                scriptPubKey: fixture.script,
1765
                value: fixture.value
1766
            }];
1767
1768
            var outputs = Wallet.convertPayToOutputs(pay, network);
1769
            test(outputs);
1770
1771
            pay = {};
1772
            pay[fixture.address] = fixture.value;
1773
1774
            // should deal with simple mapping form
1775
            outputs = Wallet.convertPayToOutputs(pay, network);
1776
            test(outputs);
1777
1778
            // repeating the procedure should pass the same test
1779
            outputs = Wallet.convertPayToOutputs(outputs, network);
1780
            test(outputs);
1781
1782
            cb();
1783
        });
1784
    });
1785
});
1786
1787
describe('test wallet coin selection forms', function() {
1788
    var wallet;
1789
1790
    it("BTC testnet wallet should exist", function(cb) {
1791
        client.initWallet({
1792
            identifier: "unittest-transaction",
1793
            passphrase: "password"
1794
        }, function(err, _wallet) {
1795
            assert.ifError(err);
1796
            assert.ok(_wallet);
1797
1798
            wallet = _wallet;
1799
1800
            client.allWallets({page: 1}, function(err, wallets) {
1801
                assert.ifError(err);
1802
1803
                assert.ok(wallets['data'].length > 0);
1804
1805
                assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1806
                assert.equal(wallet.identifier, "unittest-transaction");
1807
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1808
1809
                cb();
1810
            });
1811
        });
1812
    });
1813
1814
    it("shouldnt coin select for wrong network", function(cb) {
1815
        var pay = {};
1816
        pay["bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42"] = 10000;
1817
        wallet.coinSelection(pay, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1818
            assert.ok(err);
1819
            cb();
1820
        });
1821
    });
1822
1823
    var fixtures = [
1824
        {"tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs": 10000},
1825
        {"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7": 10000},
1826
        [
1827
            {
1828
                "address": "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1829
                "value": 10000
1830
            },
1831
            {
1832
                "address": "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1833
                "value": 10000
1834
            }
1835
        ],
1836
        [
1837
            {
1838
                "scriptPubKey": "00149bce9399f9eeddad66635d4be171ec8f14decc59",
1839
                "value": 10000
1840
            },
1841
            {
1842
                "address": "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1843
                "value": 10000
1844
            }
1845
        ]
1846
    ];
1847
1848
    fixtures.map(function(fixture) {
1849
        var type = "object";
1850
        if (Array.isArray(fixture)) {
1851
            type = "outputs array";
1852
        }
1853
        it("should coin select for " + type, function(cb) {
1854
            wallet.coinSelection(fixture, false, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1855
                assert.ifError(err);
1856
                cb();
1857
            });
1858
        });
1859
    });
1860
});
1861
1862
describe('test wallet list transactions and addresses', function() {
1863
    var wallet;
1864
1865
    it("should exists", function(cb) {
1866
        client.initWallet({
1867
            identifier: "unittest-transaction",
1868
            passphrase: "password"
1869
        }, function(err, _wallet) {
1870
            assert.ifError(err);
1871
            assert.ok(_wallet);
1872
1873
            wallet = _wallet;
1874
1875
            client.allWallets({page: 1}, function(err, wallets) {
1876
                assert.ifError(err);
1877
1878
                assert.ok(wallets['data'].length > 0);
1879
1880
                assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1881
                assert.equal(wallet.identifier, "unittest-transaction");
1882
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1883
1884
                cb();
1885
            });
1886
        });
1887
    });
1888
1889
    it("should list expected transactions", function(cb) {
1890
        wallet.transactions({page: 1, limit: 23}, function(err, transactions) {
1891
            assert.ifError(err);
1892
            assert.ok(transactions['data']);
1893
            assert.ok(transactions['total']);
1894
            assert.ok(transactions['data'].length === 23);
1895
            assert.ok(transactions['data'][0]['hash'], "2cb21783635a5f22e9934b8c3262146b42d251dfb14ee961d120936a6c40fe89");
1896
1897
            cb();
1898
        });
1899
    });
1900
1901
    it("should list expected addresses", function(cb) {
1902
        wallet.addresses({page: 1, limit: 23}, function(err, addresses) {
1903
            assert.ifError(err);
1904
            assert.ok(addresses['data']);
1905
            assert.ok(addresses['total']);
1906
            assert.ok(addresses['data'].length === 23);
1907
            assert.ok(addresses['data'][0]['address'], "2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS");
1908
1909
            cb();
1910
        });
1911
    });
1912
1913
    it("should list UTXOs", function(cb) {
1914
        wallet.utxos({page: 0, limit: 23}, function(err, addresses) {
1915
            assert.ifError(err);
1916
            assert.ok(addresses['data']);
1917
            assert.ok(addresses['total']);
1918
            assert.ok(addresses['data'].length === 23);
1919
1920
            cb();
1921
        });
1922
    });
1923
});
1924
1925
describe("size estimation", function() {
1926
1927
    it("should estimate proper size for 1 input 1 output TX", function() {
1928
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1929
        txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', 0);
1930
        txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1931
1932
        assert.equal(347, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1933
    });
1934
1935
    it("should estimate proper size for 99 inputs 1 output TX", function() {
1936
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1937
        for (var i = 0; i < 99; i++) {
1938
            txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', i);
1939
        }
1940
        txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1941
1942
        assert.equal(29453, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1943
    });
1944
1945
    it("should estimate proper size for 1 input 99 outputs TX", function() {
1946
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1947
        txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', 0);
1948
        for (var i = 0; i < 99; i++) {
1949
            txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1950
        }
1951
1952
        assert.equal(3679, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1953
    });
1954
});
1955
1956
describe("APIClient", function() {
1957
    it("resolvePrimaryPrivateKeyFromOptions", function(cb) {
1958
        client.resolvePrimaryPrivateKeyFromOptions({
1959
            passphrase: "password",
1960
            primaryMnemonic: "give pause forget seed dance crawl situate hole keen"
1961
        }, function(err, options) {
1962
            assert.ifError(err);
1963
            assert.ok(options.primaryPrivateKey);
1964
            assert.ok(options.primaryPrivateKey instanceof bitcoin.HDNode);
1965
            assert.equal("tprv8ZgxMBicQKsPeR93md5eVTbLDgQ8kfV4CDNtrVXv5p29KXtx7VHKFQThGkFgC61sYeeeaVH1yFv4thcvxS9cYdFrYwTNmkGhkQEJycSzAhE", options.primaryPrivateKey.toBase58());
1966
1967
            cb();
1968
1969
        });
1970
    });
1971
});
1972